// assets/scripts/GuideSystem/GuideManager.ts
import { setGuideConfig, GuideStep, getGuideConfig } from "./GuideConfig";
import { CLICK_TARGETS, WAIT_EVENTS } from "./GuideMapping";
import { parseCSV } from "./csvParser";
import GuideView from "./GuideView";
import { get } from "http";
const { ccclass } = cc._decorator;

const STORAGE_KEY = "GAME_GUIDE_STATE";

interface IGuideState {
  completedSteps: string[];
}

// --- 类型守卫 ---
function isClickStep(
  step: GuideStep
): step is GuideStep & { targetNodePath: string } {
  return "targetNodePath" in step;
}

function isWaitStep(
  step: GuideStep
): step is GuideStep & { waitForEvent: string } {
  return "waitForEvent" in step;
}

@ccclass
export class GuideManager {
  private static _instance: GuideManager;
  public static get instance() {
    if (!this._instance) {
      this._instance = new GuideManager();
    }
    return this._instance;
  }

  private view: GuideView | null = null;
  private state: IGuideState = { completedSteps: [] };

  // 当前引导上下文
  private currentGroupId: string | null = null;
  private currentStepIndex: number = -1;
  private isWaitingForEvent: boolean = false; // 防止重复监听

  // ----------------------------
  // 初始化 & 状态管理
  // ----------------------------

  async init(guideView: GuideView) {
    await this.loadGuideConfig();
    this.view = guideView;
    this.loadState();
  }

  async loadGuideConfig(): Promise<void> {
    return new Promise((resolve, reject) => {
      cc.resources.load(
        "csv/guide_steps",
        cc.TextAsset,
        (err, asset: cc.TextAsset) => {
          if (err) {
            cc.error("[Guide] Failed to load guide_steps.csv:", err);
            reject(err);
            return;
          }

          try {
            const rows = parseCSV(asset.text);
            const config: Record<string, GuideStep[]> = {};

            for (const row of rows) {
              const { group, id, tipText = "" } = row;
              // cc.log("[Debug] Processing ID:", id);
              // cc.log("[Debug] CLICK_TARGETS keys:", Object.keys(CLICK_TARGETS));
              // cc.log("[Debug] WAIT_EVENTS keys:", Object.keys(WAIT_EVENTS));
              if (!group || !id) {
                cc.warn(
                  "[Guide] Skip invalid step (missing group or id):",
                  row
                );
                continue;
              }

              // ✅ 核心：从 GuideMapping 获取，不看 CSV 的 targetNodePath / waitForEvent
              const realTargetPath =
                CLICK_TARGETS[id as keyof typeof CLICK_TARGETS];
              const realWaitEvent = WAIT_EVENTS[id as keyof typeof WAIT_EVENTS];

              let step: GuideStep;

              if (realWaitEvent !== undefined) {
                step = { id, group, waitForEvent: realWaitEvent, tipText };
              } else if (realTargetPath !== undefined) {
                step = { id, group, tipText, targetNodePath: realTargetPath };
              } else {
                cc.error(
                  `[Guide] ID "${id}" not found in GuideMapping.ts!`,
                  row
                );
                continue; // 跳过无效ID
              }

              if (!config[group]) config[group] = [];
              config[group].push(step);
            }

            // ✅ 构建全局配置（GUIDE_CONFIG 必须是 let！）
            setGuideConfig(config);

            cc.log("[Guide] Config loaded successfully:", getGuideConfig());
            resolve();
          } catch (e) {
            cc.error("[Guide] Parse CSV error:", e);
            reject(e);
          }
        }
      );
    });
  }

  private loadState() {
    const saved = cc.sys.localStorage.getItem(STORAGE_KEY);
    if (saved) {
      try {
        const parsed = JSON.parse(saved);
        if (Array.isArray(parsed?.completedSteps)) {
          this.state = parsed;
        }
      } catch (e) {
        console.warn("[Guide] Failed to parse state, resetting.");
        this.state = { completedSteps: [] };
      }
    }
  }

  private saveState() {
    cc.sys.localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state));
  }

  // ----------------------------
  // 查询接口
  // ----------------------------

  isStepCompleted(stepId: string): boolean {
    return this.state.completedSteps.includes(stepId);
  }

  isGroupCompleted(groupId: string): boolean {
    const steps = getGuideConfig()[groupId];
    return (
      !steps ||
      steps.length === 0 ||
      steps.every((step) => this.isStepCompleted(step.id))
    );
  }

  // ----------------------------
  // 引导控制
  // ----------------------------

  startGuideIfNeeded(groupId: string) {
    if (this.isGroupCompleted(groupId)) {
      console.log(`[Guide] Group "${groupId}" already completed.`);
      return;
    }

    const steps = getGuideConfig()[groupId];
    if (!steps || steps.length === 0) {
      console.warn(`[Guide] Group "${groupId}" not found or empty.`);
      return;
    }

    const firstIncompleteIndex = steps.findIndex(
      (step) => !this.isStepCompleted(step.id)
    );
    if (firstIncompleteIndex < 0) return;

    this.currentGroupId = groupId;
    this.currentStepIndex = firstIncompleteIndex;
    this.isWaitingForEvent = false;
    this.showCurrentStep();
  }

  private showCurrentStep() {
    const step = this.getCurrentStep();
    if (!step) {
      this.endCurrentGuide();
      return;
    }

    if (isClickStep(step)) {
      this.view?.show(step);
      console.log("click型引导");
    } else if (isWaitStep(step)) {
      this.startWaitingForEvent(step.waitForEvent);
      console.log("wait型引导");
    }
  }

  private getCurrentStep(): GuideStep | null {
    if (!this.currentGroupId || this.currentStepIndex < 0) return null;
    const steps = getGuideConfig()[this.currentGroupId];
    if (!steps || this.currentStepIndex >= steps.length) return null;
    return steps[this.currentStepIndex];
  }

  private startWaitingForEvent(event: string) {
    if (this.isWaitingForEvent) return; // 防止重复注册

    this.isWaitingForEvent = true;
    console.log(`[Guide] Waiting for event: ${event}`);
    cc.systemEvent.on(event, this.onWaitEventFulfilled, this);
  }

  private onWaitEventFulfilled(event: string) {
    const step = this.getCurrentStep();
    if (!step || !isWaitStep(step) || step.waitForEvent !== event) return;

    cc.systemEvent.off(event, this.onWaitEventFulfilled, this);
    this.isWaitingForEvent = false;

    this.markStepCompleted(step.id);
    this.currentStepIndex++;
    this.showCurrentStep();
  }

  // ----------------------------
  // 外部交互：GuideView 调用
  // ----------------------------

  onTargetClicked(clickedStep: GuideStep) {
    const currentStep = this.getCurrentStep();
    if (!currentStep || currentStep.id !== clickedStep.id) {
      console.warn("[Guide] Clicked step does not match current step.");
      return;
    }
    // 完成当前点击步骤（只做一次）
    this.markStepCompleted(currentStep.id);
    this.currentStepIndex++;
    this.showCurrentStep();
  }

  private getNextStep(): GuideStep | null {
    if (!this.currentGroupId) return null;
    const steps = getGuideConfig()[this.currentGroupId];
    const nextIndex = this.currentStepIndex + 1;
    return steps && nextIndex < steps.length ? steps[nextIndex] : null;
  }

  // ----------------------------
  // 通用工具
  // ----------------------------

  private markStepCompleted(stepId: string) {
    if (!this.isStepCompleted(stepId)) {
      this.state.completedSteps.push(stepId);
      this.saveState();
    }
  }

  private endCurrentGuide() {
    this.currentGroupId = null;
    this.currentStepIndex = -1;
    this.isWaitingForEvent = false;
    console.log("结束当前引导，引导界面隐藏");
    this.view?.hide();
  }

  // ----------------------------
  // 调试工具
  // ----------------------------

  resetAll() {
    this.state = { completedSteps: [] };
    this.saveState();
    console.log("[Guide] All guide states reset.");
  }
}
